//
// Test Arduino sketch for GP2Y1010AU0F dust sensor
// 
// original code created by SenSorApp.net
//     http://sensorapp.net/?p=479
//

// defines for setting and clearing register bits
//   (used to be in WinAVR inculde file)
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

// for dust sensor
int dustPin=0;      // analog pin # for input
int sensorLedPin=6;     // power internal LED of sensor

// for shift registor (conneted to LEDs)
int clockPin = 12;
int dataPin  = 11;

// on board LED
int indicatorPin = 13;


#define NUM_LED 7
int dustSign[NUM_LED] = {0, 204,307,409,512,614,716};


int g1Pin = 7;
int g2Pin = 8;
int y1Pin = 9;
int y2Pin = 10;
int y3Pin = 11;
int r1Pin = 12;
int r2Pin = 13;

#define SENSE_CNT 3


int delayTime=280;  // microseconds
int delayTime2=27;  // (40 - 13) microseconds
float offTime=9680; // microseconds
int sleepTime=3000;

void setup(){
  Serial.begin(9600);
  pinMode(sensorLedPin,OUTPUT);
  pinMode(indicatorPin,OUTPUT);

  pinMode(g1Pin, OUTPUT);
  pinMode(g2Pin, OUTPUT);
  pinMode(y1Pin, OUTPUT);
  pinMode(y2Pin, OUTPUT);
  pinMode(r1Pin, OUTPUT);
  pinMode(r2Pin, OUTPUT);

  // set ADC prescale to 16 (default is 128)
  // this will reduce A/D time from 104 usec to 13 usec (in 16MHz environment)
  sbi(ADCSRA,ADPS2) ;
  cbi(ADCSRA,ADPS1) ;
  cbi(ADCSRA,ADPS0) ;

}

void loop(){
  /*
  int dustVal = senseData();
  Serial.print("sensor read :");
  Serial.println(dustVal);
  turnOnLED(dustVal);
  delay(sleepTime);
  */
  // FOR H/W DEBUG USE
  for (int d= 0 ; d < 800 ; d+=30 ){
    turnOnLED(d);
    delay(10);
  }
  for (int d= 800 ; d > 0 ; d -=30 ){
    turnOnLED(d);
    delay(10);
  }
  // DEBUG END
 

}

int senseData()
{
  int v ; 
  int vtemp[SENSE_CNT];
  int s=0;
  
  digitalWrite(indicatorPin, HIGH);

  for (int i=0 ; i<SENSE_CNT ; i++) {
    // sensorLedPin is any digital pin on the arduino connected to Pin 3 on the sensor
    digitalWrite(sensorLedPin,LOW); // power on the LED
    delayMicroseconds(delayTime);
    vtemp[i]=analogRead(dustPin); // read the dust value via pin 5 on the sensor
    delayMicroseconds(delayTime2);
    digitalWrite(sensorLedPin,HIGH); // turn the LED off
    delayMicroseconds(offTime);

  }
  digitalWrite(indicatorPin, LOW);
  for (int i=0; i< SENSE_CNT ; i++) {
    s += vtemp[i];
    Serial.print(vtemp[i]);
    Serial.print (" ");
  }
  Serial.println();
  
  return s/SENSE_CNT;
}

void turnOnLED(int dustVal) {
  
  int reg=0;
  
  for (int i=0; i < NUM_LED ; i++){
    if ( dustVal > dustSign[i] ) {
      reg |= _BV(i);
    }
  }
  
  shiftOut(dataPin, clockPin, MSBFIRST, reg);

}


